home *** CD-ROM | disk | FTP | other *** search
- #!/bin/sh
- PATH=:/bin:/usr/bin:/usr/ucb:/usr/local/bin
- # -------------------------------------------------------------
- # Copyright (c) 1989, 1993, 1994
- # Regents of the University of Michigan. All rights reserved.
- #
- # Redistribution and use is permitted provided that this notice
- # is preserved and that due credit is given to the University of
- # Michigan. The name of the University may not be used to endorse
- # or promote products derived from this software without specific
- # prior written permission. This software is provided "as is"
- # without express or implied warranty.
- #
- # DNS Statistics gatherer
- # Author: Bryan Beecher
- # Last Modified: 6/14/94
- #
- # To make use of this software, you need to be running a copy of
- # BIND 4.9 (or later) compiled with the QRYLOG option defined.
- #
- # The assumption behind this script is that it will be run out
- # of crontab daily just before some sort of syslog manager
- # copies the current contents of LOGFILE elsewhere before
- # emptying the LOGFILE. However, it can certainly be run on
- # a LOGFILE that is not emptied daily, and in this case it
- # would merely report the cumulative statistics.
- # -------------------------------------------------------------
-
- # -------------------------------------------------------------
- # C O N F I G U R A T I O N S E C T I O N
- # -------------------------------------------------------------
-
- ##
- ## NOTE: Ultrix users may want to change the first line
- ## of this script from /bin/sh to /bin/sh5.
- ##
-
- # -------------------------------------------------------------
- # Do we use 'getopts' or 'getopt'?
- # -------------------------------------------------------------
- GETOPT=getopts
-
- # -------------------------------------------------------------
- # This is the name of the log.
- # -------------------------------------------------------------
- LOGFILE=/var/log/named
-
- # -------------------------------------------------------------
- # This is the program we use to go from an IP addr to host
- # -------------------------------------------------------------
- QUERYPROG="/usr/local/bin/dig -x"
-
- # -------------------------------------------------------------
- # This is the awk we use.
- # -------------------------------------------------------------
- AWK=/bin/awk
-
- # -------------------------------------------------------------
- # This is the directory in which we should create temp files
- # -------------------------------------------------------------
- TMPDIR=/usr/tmp
-
- # -------------------------------------------------------------
- # This is the default number of entries we want printed in
- # each category of statistics.
- # -------------------------------------------------------------
- STOPAT=25
-
- # -------------------------------------------------------------
- # E N D O F C O N F I G U R A T I O N S E C T I O N
- # -------------------------------------------------------------
-
- # -------------------------------------------------------------
- # handy files
- # -------------------------------------------------------------
- TMPFILE=$TMPDIR/.dnsstats$$
-
- ADDRFILE=$TMPDIR/.addrs$$
- NAMEFILE=$TMPDIR/.names$$
- TYPEFILE=$TMPDIR/.types$$
- WEEKFILE=$TMPDIR/.week$$
- TOTALFILE=$TMPDIR/.total$$
-
- # -------------------------------------------------------------
- # handle arguments
- # -------------------------------------------------------------
- # -d <day>
- # This flag is used to append a dot-day suffix to the LOGFILE.
- # Handy where log files are kept around for the last week
- # and contain a day suffix.
- #
- # -f <logfile>
- # Change the LOGFILE value altogether.
- #
- # -n
- # Don't try to resolve IP addresses from in-addr.arpa names
- # to "regular" names. Handy if the DNS is slow or you just
- # don't care about the domain names associated with the IP
- # addresses.
- #
- # -w
- # Count up all of the DNS statistics for the whole week.
- #
- # -c <#>
- # Print only the top-# of entries in each category.
- # Default is $STOPAT.
- #
- # -a
- # Print the entire list of entries in each category.
- # -------------------------------------------------------------
- NONAMES=0
- PRINTALL=0
-
- trap "rm -f $TMPFILE $ADDRFILE $NAMEFILE $TYPEFILE $WEEKFILE $TOTALFILE; exit 0" 0 1 2 3 15
-
- gethostbyaddr() {
- $QUERYPROG $ADDRESS | $AWK ' BEGIN {
- msg = " ** Query failed ** "
- }
- $3 == "PTR" {
- msg = substr($4, 1, length($4) - 1)
- }
- END {
- printf(" %6d %-39s [%s]\n", count, msg, address)
- }' count=$COUNT address=$ADDRESS - ;
- }
-
- if [ $GETOPT = "getopts" ] ; then
- while getopts ac:d:f:nw ARG ; do
- case $ARG in
- a) PRINTALL=1
- ;;
- c) STOPAT=$OPTARG
- ;;
- d) LOGFILE=$LOGFILE"."$OPTARG
- ;;
- f) LOGFILE=$OPTARG
- ;;
- n) NONAMES=1
- ;;
- w) cat $LOGFILE* > $WEEKFILE
- LOGFILE=$WEEKFILE
- ;;
-
- esac
- done
- shift `expr $OPTIND - 1`
- else
- set -- `getopt ac:d:f:nw $*`
- if [ $? != 0 ] ; then
- exit 2
- fi
- for ARG in $* ; do
- case $ARG in
- -a) PRINTALL=1
- shift
- ;;
- -c) STOPAT=$2
- shift 2
- ;;
- -d) LOGFILE=$LOGFILE"."$2
- shift 2
- ;;
- -f) LOGFILE=$2
- shift 2
- ;;
- -n) NONAMES=1
- shift
- ;;
- -w) cat $LOGFILE* > $WEEKFILE
- LOGFILE=$WEEKFILE
- shift
- ;;
- --) shift
- break
- ;;
- esac
- done
- fi
-
- # -------------------------------------------------------------
- # divide the log file into three files:
- # one for source addrs of incoming querys
- # one for domain names that were queried upon
- # one for query types
- # -------------------------------------------------------------
- $AWK '
- {
- if ((n == 0) && ($5 == "last"))
- next
- else if ($5 == "last") {
- total += $8
- sender[info[2]] += $8
- query[info[3]] += $8
- querytype[info[4]] += 8
- }
- else if ($6 == "XX") {
- n = split($0, info, "/")
- if (n == 4) {
- total++
- sender[info[2]]++
- query[info[3]]++
- querytype[info[4]]++
- }
- }
- else {
- n = 0
- }
- }
- END {
- if (total > 0) {
- for (i in sender)
- print sender[i], i >f1
- for (i in query)
- print query[i], i >f2
- for (i in querytype)
- print querytype[i], i >f3
- print total >f4
- }
- }' f1=$ADDRFILE f2=$NAMEFILE f3=$TYPEFILE f4=$TOTALFILE $LOGFILE
-
- # -------------------------------------------------------------
- # Bail out if info was not produced
- # -------------------------------------------------------------
- if [ ! -s $ADDRFILE -a -s $NAMEFILE -a -s $TYPEFILE -a -s $TOTALFILE ] ; then
- echo "No data on which to operate"
- rm -f $TMPFILE $ADDRFILE $NAMEFILE $TYPEFILE $WEEKFILE $TOTALFILE
- exit 0
- fi
-
- # -------------------------------------------------------------
- # Print some general information
- # -------------------------------------------------------------
- echo "DNS stats for" `hostname` "for period ending" `ls -l $LOGFILE | $AWK '{ print $5, $6, $7 }'`
- echo "Total queries received: " `cat $TOTALFILE`
- echo
- echo "Part I -- query sources"
- echo
-
- # -------------------------------------------------------------
- # First, tell who was querying this nameserver
- # -------------------------------------------------------------
- if [ $NONAMES -eq 0 ] ; then
- echo " Number Source (by name if available) IP address"
- echo " ------ ----------------------------- ----------"
- sort -rn $ADDRFILE > $TMPFILE
- if [ $PRINTALL -eq 1 ] ; then
- mv $TMPFILE $ADDRFILE
- else
- head -$STOPAT $TMPFILE > $ADDRFILE
- fi
- while [ 1 ] ; do
- read COUNT ADDRESS
- if [ $? -ne 0 ] ; then
- break
- fi
- gethostbyaddr
- done < $ADDRFILE
- else
- echo " Number IP address"
- echo " ------ ----------"
- sort -rn $ADDRFILE > $TMPFILE
- if [ $PRINTALL -eq 1 ] ; then
- $AWK '{ printf(" %6d [%s]\n", $1, $2) }' $TMPFILE
- else
- head -$STOPAT $TMPFILE | $AWK '{ printf(" %5d [%s]\n", $1, $2) }'
- fi
- fi
-
- # -------------------------------------------------------------
- # Second, tell what names were being queried upon
- # -------------------------------------------------------------
- echo
- echo "Part II -- queried names"
- echo
- echo " Number Queried name"
- echo " ------ ------------"
- sort -rn $NAMEFILE > $TMPFILE
- if [ $PRINTALL -eq 1 ] ; then
- $AWK '{ printf(" %6d %s\n", $1, $2) }' $TMPFILE
- else
- head -$STOPAT $TMPFILE | $AWK '{ printf(" %6d %s\n", $1, $2) }'
- fi
-
- # -------------------------------------------------------------
- # Third, tell what sort of queries there were
- # -------------------------------------------------------------
- echo
- echo "Part III -- query types"
- echo
- echo " Number Type"
- echo " ------ ----"
- sort -rn $TYPEFILE > $TMPFILE
- if [ $PRINTALL -eq 1 ] ; then
- $AWK '{ printf(" %6d %s\n", $1, $2) }' $TMPFILE
- else
- head -$STOPAT $TMPFILE | $AWK '{ printf(" %6d %s\n", $1, $2) }'
- fi
-
- # -------------------------------------------------------------
- # Last, tidy things up
- # -------------------------------------------------------------
- rm -f $TMPFILE $ADDRFILE $NAMEFILE $TYPEFILE $WEEKFILE $TOTALFILE
-